package geektime.spring.springbucks.waiterservice.controller;

import geektime.spring.springbucks.waiterservice.controller.request.NewOrderRequest;
import geektime.spring.springbucks.waiterservice.model.Coffee;
import geektime.spring.springbucks.waiterservice.model.CoffeeOrder;
import geektime.spring.springbucks.waiterservice.service.CoffeeOrderService;
import geektime.spring.springbucks.waiterservice.service.CoffeeService;
import java.util.List;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/order")
@Slf4j
public class CoffeeOrderController {

  @Autowired
  private CoffeeOrderService coffeeOrderService;

  @Autowired
  private CoffeeService coffeeService;

  @GetMapping("/{id}")
  @ResponseBody
  public CoffeeOrder getOrder(@PathVariable("id") Long id) {
    return coffeeOrderService.get(id);
  }

  @PostMapping(path = "/", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  @ResponseStatus(HttpStatus.CREATED)
  @ResponseBody
  public CoffeeOrder create(@RequestBody NewOrderRequest newOrder) {
    log.info("Receive new Order {}", newOrder);

    Coffee[] coffees = coffeeService.getCoffeeByName(newOrder.getItems()).toArray(new Coffee[]{});

    return coffeeOrderService.createOrder(newOrder.getCustomer(), coffees);
  }


  @ModelAttribute
  public List<Coffee> coffeeList() {
    return coffeeService.getAllCoffee();
  }

  @GetMapping(path = "/")
  public ModelAndView showCreateForm() {
    return new ModelAndView("create-order-form");
  }

  @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
  public String createOrder(@Valid NewOrderRequest newOrder, BindingResult result, ModelMap map) {

    if (result.hasErrors()) {
      log.warn("Binding Result :{}", result);
      map.addAttribute("message", result.toString());
      return "create-order-form";
    }

    log.info("Receive new Order{}", newOrder);
    Coffee[] coffees = coffeeService.getCoffeeByName(newOrder.getItems()).toArray(new Coffee[]{});
    CoffeeOrder order = coffeeOrderService.createOrder(newOrder.getCustomer(), coffees);
    return "redirect:/order/" + order.getId();
  }
}
